import re

__author__ = 'YeeHin Kwok'



""" Giovanni's MicroCompiler Demo

<program>       ::=     { <id> ; <vars > <stmtlist>  }
<vars>          ::=     V { <id> ; }                       % DECLARATIONS

<stmtlist>      ::=     <stmt> { ; <stmt> }
<stmt>          ::=     P <id>  |  <id> = <expr>

<expr>          ::=     <factor> {  (+ | -)   <factor> }   % No precedence
<factor>                ::=     ID | Number

"""

import sys
import shlex

#===============================================================================
# # Lexical Analyser - the "Scanner" - Define the TokenTypes
#===============================================================================

tokenNames = \
  [ "unknownToken", "idsym", "assignsym", "leftbrace", "rightbrace",
    "varsym", "semicolon", "whilesym", "leftbracket", "rightbracket",
    "printsym", "ifsym", "equals", "lessthan", "greaterthan",
    "number", "plus", "minus", "mpy", "div", "elsesym", "declaresym", "forsym", "andsym", "elifsym", "dosym", "returnsym",
    "continuesym", "breaksym", "nonesym", "programsym", "functionsym", "leftsquarebrace", "rightsquarebrace",
    "lessthanequal", "colon", "comma", "comment", "commentstr", "dot", " greaterthanequal", "jumpeq", "jumpne",
    "andop", "orop", "quote ", "stringsym", "arraysym", "readsym", "endfile"]

# define the tokens as variables
unknownToken, idsym, assignsym, leftbrace, rightbrace, \
    varsym, semicolon, whilesym, leftbracket, rightbracket, \
    printsym, ifsym, equals, lessthan, greaterthan, \
    number, plus, minus, mpy, div, elsesym, declaresym, forsym, andsym, elifsym, dosym, returnsym, \
    continuesym, breaksym, nonesym, programsym, functionsym, leftsquarebrace, rightsquarebrace, \
    lessthanequal, colon, comma, comment, commentstr, dot, greaterthanequal, jumpeq, jumpne, \
    andop, orop, quote, stringsym, arraysym, readsym, endfile = range(0, len(tokenNames))

#===============================================================================
class symbol:
#===============================================================================
    name = None  # String representation
    token = None;  # Corresponding token
    address = 0;  # For variables, their runtime address
    value = None  # on defined for numbers
    

    def __init__(self, name, token, value=0):
        self.name = name
        self.token = token
        self.address = 0  # for identifiers, their address
        self.value = value  # for numbers, their value


symtbl = {};  # The Symbol Table, a dictionary of symbols indexed by name

#======================================================================
# GLOBALS for output of Lexical Analyser
# Set by each call to GeToken()

token = None;  # A symbol
line = "\n"  # the complex source file as a string
charIndex = 0  # the position in the source

linenumber = 0  # The current  number

i = 100
j = 100 
counterafter = i
counterafter1 = j


EOF = chr(0)
#======================================================================
# Run Time Code Generation Variables

varptr = 500  # Arbitrary base address of memory for variables
codeptr = 10  # Address to output next instruction (for code)


#===============================================================================
#                    Symbol Table Management Routines
#===============================================================================

#===============================================================================
def addToSymTbl (name, token):
#===============================================================================
    symtbl[name] = symbol(name, token)  # Add a new symbol to the dictionary
    return symtbl[name]


#===============================================================================
def lookup (thisName):
#===============================================================================
    "# Find a given identifier in the Symbol Table, Return the symtbl entry"
    if symtbl.has_key(thisName):  # thisName has been seen before
        return symtbl[thisName]  # return the symtbl entry
    else: return None


#===============================================================================
def initSymTbl():
#===============================================================================
    "# Initialise Symbol Table, and preload reserved words"
    addToSymTbl('var', varsym)  # VAR
    addToSymTbl('program', programsym)
    addToSymTbl('function', functionsym)
    addToSymTbl('while', whilesym)  # WHILE
    addToSymTbl('print', printsym)  # PRINT
    addToSymTbl('else', elsesym)
    addToSymTbl('elif', elifsym)
    addToSymTbl('if', ifsym)
    addToSymTbl('declare', declaresym)
    addToSymTbl('for', forsym)
    addToSymTbl('None', nonesym)
    addToSymTbl('continue', continuesym)
    addToSymTbl('read', readsym)  # READINT
    addToSymTbl('do', dosym)
    addToSymTbl('return', returnsym)



    # Now add symbols - NB only single character symbols are here
    #                      multicharacter one like ">=" are still to do
    addToSymTbl('=', assignsym)
    addToSymTbl('#', comment)
    addToSymTbl('<', lessthan)
    addToSymTbl('>', greaterthan)
    addToSymTbl('{', leftbrace)
    addToSymTbl('}', rightbrace)
    addToSymTbl('(', leftbracket)
    addToSymTbl(')', rightbracket)
    addToSymTbl('+', plus)
    addToSymTbl('-', minus)
    addToSymTbl(';', semicolon)
    addToSymTbl('break', breaksym)
    addToSymTbl('*', mpy)
    addToSymTbl('/', div)
    addToSymTbl('[', leftsquarebrace)
    addToSymTbl(']', rightsquarebrace)
    addToSymTbl(':', colon)
    addToSymTbl(',', comma)
    addToSymTbl('.', dot)
    addToSymTbl('==', jumpeq)
    addToSymTbl('!=', jumpne)
    addToSymTbl('&&', andop)
    addToSymTbl('||', orop)
    addToSymTbl('"', quote)
    addToSymTbl(EOF, endfile)


#===============================================================================
#                       Scanner Diagnostics
#===============================================================================
def printToken(tok):
#===============================================================================
    " - display the specified token."
    if tok.token == idsym:
       print "Token = %10s,  %-10s  adr = %3d" % \
             (tokenNames[tok.token], tok.name, tok.address)
    elif tok.token == number:
       print "Token = %10s  %d" % (tokenNames[tok.token], tok.value)
    else:
       print "Token = %10s" % tokenNames[tok.token]

#==============================?=================================================
def dumpSymTbl():
#===============================================================================
    """ Dump all the tokens in the symboltable """
    print(" *** Symbol Table ***")
    for name in symtbl.keys():  # keys is a list of the names (printable form of tokens)
        tok = symtbl[name]
        if tok.token == idsym:
            printToken(tok)

#===============================================================================
def getch():
#===============================================================================
    global line
    global charIndex
    global linenumber

    while True:
        if charIndex < len(line):  # See if used up current line
            ch = line[charIndex]  # if not, get character
            charIndex = charIndex + 1  # & move pointer for next time
        else:
            
            # line = f.readline()
            # if  line == "": line = EOF
            print "#End of File"
            print "#--> ",
            line = raw_input() + "\n"  # read new line, adding \n so it's like f.readline()
#            line = srcfile.read()
            charIndex = 0  # & reset character pointer
            linenumber = linenumber + 1
            continue

        if ch == "\n":
            ch = " "

        if ch == '?':
            dumpSymTbl()
            continue
        return ch

#===============================================================================
def ungetch():
#===============================================================================
    """ Unget the next character peeked at when building variables, numbers
        and when distinguishing between >= and > ...
    """
    global charIndex;
    charIndex = charIndex - 1;

#===============================================================================
def getoken():
#===============================================================================
    """ GETOKEN - Put next token into the global TOKEN """
    global token
    global i
    global m
    global counterafter
    global counterafter1
    x = 0
    ch = getch()  # skip whitespace
    while ch in ["\t", " ", "\n"]:
        ch = getch()

    # If ch is alphabetic then this is start of reserved word or an identifier
    if ch.isalpha():  # Letter therefore it's either identifier or reserved word
        name = ""
        while ch.isalpha() or ch.isdigit() or ch == "_":
            name = name + ch
            ch = getch()

        ungetch()  # let terminator be used next time

        token = lookup(name)  # See if token's known
        if token is None:  # if not
            token = addToSymTbl(name, idsym)  #   add as 'idsym'-IDENTIFIER

        return  # we've set token.token to either id or tokentype of reserved word

    elif ch in ["{", "}", "(", ")", "[", "]", "+", "-", "*", "/", ";", ",", ":", EOF]:
        token = lookup(ch)  # preloaded with appropriate token

    elif ch.isdigit():

        # In the real version, build number and don't forget to end with ungetch()
        while(ch.isdigit() == True):
            x = str(x) + str(ch)
            ch = getch()
        ch = ungetch()

        token = symbol(x, number, value=int(x))  # simplistic SINGLE DIGIT Ascii to Binary
        return

    # elif ch == "-":
    #     x = ""
    #     no =""
    #     ch = getch()
    #     if ch.isdigit() ==True:
    #         while ch.isdigit():
    #             x = str(x) + str(ch)
    #             ch = getch()
    #
    #         ch = ungetch()
    #
    #         no = "-" + str(x)
    #
    #         token = symbol(no, number, value = int(no))

    elif ch == '#':
        str1 = ""
        ch = getch()

        while(ch != " "):
            str1 = str(str1) + str(ch)

            ch = getch()

        ch = getch()

        token = symbol(str1, commentstr, value=str(str1))  # simplistic SINGLE DIGIT Ascii to Binary
        print("#comment: " + str(str1))
        return
    
    elif ch == '"':
        a = ""
        
        ch = getch()
        
        counterafter1 =counterafter
                    
        i=counterafter
        if counterafter != 100:
            counterafter=counterafter+4;
            counterafter = i
            
        
        while (ch != '"'):
            
            a = str(a) + str(ch)
            if ch != " ":
                b = "'"+ch+"'"
            emit(i, "constant",b)
            ch = getch()
            i=i+1 
        emit(i, "constant", 13)
        emit(i+1, "constant", 0)
#       emit(i+2, "writech", '')
        emit(i+2, "return", '')
        ch = getch()
        counterafter=i+3

        token = symbol(a, stringsym, value=str(a))  # simplistic SINGLE DIGIT Ascii to Binary
        
        
#        printMsg()
        return
    elif ch == "<":

        ch = getch()
        if ch == "=":
            lt = ""
            lt = "<" + "="

            token = symbol(lt, lessthanequal, value=str(lt))  # simplistic SINGLE DIGIT Ascii to Binary
            return
        else:
            ch == ungetch()
            token = symbol("<", lessthan, value="<")  # simplistic SINGLE DIGIT Ascii to Binary
            return
    elif ch == "!":
        ne = ""
        ch = getch()
        if ch == "=":
            ne = "!" + "="

            token = symbol(ne, jumpne, value=str(ne))  # simplistic SINGLE DIGIT Ascii to Binary
            return
        else:
            ch == ungetch()
            token = symbol("!", NOT , value="!")  # simplistic SINGLE DIGIT Ascii to Binary
            return
    
    elif ch == "=":

        eq = ""
        ch = getch()
        if ch == "=":
            
            eq = "=" + "="

            token = symbol(eq, jumpeq, value=str(eq))  # simplistic SINGLE DIGIT Ascii to Binary
            return
        else:
            ch == ungetch()
            token = symbol("=", assignsym, value="=")  # simplistic SINGLE DIGIT Ascii to Binary
            return
        
    elif ch == ">":

        gt = ""
        ch = getch()
        if ch == "=":
            gt = ">" + "="

            token = symbol(gt, lessthanequal, value=str(gt))  # simplistic SINGLE DIGIT Ascii to Binary
            return
        else:
            ch == ungetch()
            token = symbol(">", greaterthan, value=">")  # simplistic SINGLE DIGIT Ascii to Binary
            return
    else:
        print "Unknown character -->%s<- decimal %d" % (ch, ord(ch))
        sys.exit(1)  # Abort Compilation

#======================================================================
# THE GRAMMAR

# <program>       ::=     { <id> ; <vars > <stmtlist>  }
# <vars>          ::=     var { <id> ; }                    % DECLARATIONS
# <array>         ::=     [<expr>]

# <stmtlist>      ::=     <stmt> { ; <stmt> }
# <stmt>          ::=     print <id>
#                         <id> = <expr>

# <expr>          ::=     <factor> {  (+ | - | * | /)   <factor> }   % No precedence
# <factor>        ::=     [+/-] ID | Number

#======================================================================
#                  Centralised Parser Error Message handler
#======================================================================


#===============================================================================
def error (msg):
#===============================================================================
    print line
    print "-" * charIndex, "^"
    print("Error on  %d - %s\n" % (number, msg))
    printToken(token)
    print("\n")

#===============================================================================
def emit (memadr, opcode, parameter):
#===============================================================================
    """EMIT CODE - Emit a  of code with a Parameter
    if first arg is zero - (the memory address), use and incr CODEPTR"""
    global codeptr

    if (memadr == 0):
        memadr = codeptr
        codeptr = codeptr + 1
    print "%6d  %-8s %-7s" % (memadr, opcode, parameter)

#======================================================================
# VARIABLE DECLARATIONS
#   <vars>              ::=     V { <id> ; }

#===============================================================================
def vars() :
#===============================================================================

    ta = 0
    tn = []
    global varptr;

    getoken();

    if token.token == idsym:
        ta = token.address
        tn = token.name
        getoken()

        if token.token == leftsquarebrace:

            getoken()

            if token.token == number:
                
 #               emit(0, "loadv",token.value)
 #               emit(0, "store", token.value+300)

                array()

                if token.token == rightsquarebrace:
                    getoken()
                else:
                    error("var error: ] expected - 1")

            else: 
                getoken()
                
        elif tn == "i":
#            print("#The array name is " + str(tn)+"\n")
            
            if token.token == rightsquarebrace:
                getoken()
        else:
            if ta != 0:
                print("%c already declared\n", tn);
                #assignStmt()
            else:
                symtbl[tn].address = varptr;
                varptr = varptr + 1
#                emit(0, "load", varptr)

    if token.token == assignsym:
        getoken()

        expression()
    
    if token.token == rightbracket:
        getoken()
    if token.token == comma:
        vars()
    elif token.token == semicolon : getoken()
    
    else: error("comma or semicolon expected in declaration")

    
#===============================================================================
def array():
#===============================================================================
    global array;
#    getoken()
    while (token.token == number):
        print("#array address")
        emit(0, "store", token.value + 400)
        print("#array value " +str(token.value))
        getoken();
#======================================================================
# STMTLIST
# <stmtlist>  ::= <stmt> { ; <stmt> }

#===============================================================================
def stmtList():
#===============================================================================
    stmt()

    while (token.token != rightbrace):
        stmt()


#======================================================================
# STMT

#===============================================================================
def stmt():
#===============================================================================
    """  <stmt> ::=  print <expression|string>| read <vars>  |  <id> = <expression> | 
        if <condition> <stmt> [else <stmt>]| while <condition> <stmt>|
        <stmtList>  | do <stmsList> forever | break | continue
    """
    global codeptr

    thisStmtAdr = codeptr  # Jump DEMO - not part of Stmt
#    if token.token == arraysym:
 #       array()
    if  token.token == printsym:
        printStmt()
    elif token.token == readsym:
        readStmt()
        
    elif token.token == number:
        expression()
    elif token.token == idsym:
       assignStmt()
    
    elif token.token == ifsym:
        ifStmt()
    
    elif token.token == elsesym:
        elseStmt()
    
    elif token.token == whilesym:
        whileStmt()  
    
    elif token.token == dosym:
        doStmt()
    elif token.token == returnsym:
        expression()
    
    elif token.token == continuesym:
        continueStmt()
    
    elif  token.token == leftbracket:
        getoken()
        
    elif  token.token == leftbrace:
        getoken()

    elif token.token == stringsym:
#        print(str(token.name))
        printMsg()
        getoken()
    elif token.token == assignsym:
        getoken()
    elif token.token == commentstr:
 #       print(str(token.name))
        getoken()
        
    elif token.token == breaksym:
        getoken()

    elif token.token == lessthanequal:
       getoken()
    elif token.token == greaterthanequal:
       getoken()
       
    elif token.token == jumpeq:
        getoken()
    
    elif token.token == jumpne:
        getoken()
       
    elif  token.token == rightbracket:
        getoken()
    elif  token.token == semicolon:
        getoken()

    elif  token.token == comma:
        getoken()
    
    elif token.token == rightsquarebrace:
        getoken()

    elif token.token == rightbrace:
        getoken()
    else:
        error("Expected start of a statement")

    # emit (0, "return", thisStmtAdr)   Jump DEMO  need in break program

#===============================================================================
def printStmt():
#===============================================================================
    """   <printStmt> ::= print <expression|string>"""

    getoken()# skip "print"
    stmt()
    emit(0, "load", 501)
    expression()
    emit(0, "writeint", 502)
    emit(0, "writeint", 7)

#===============================================================================
def printMsg():
#===============================================================================
    """   <printMsg> ::= printMsg <expression>"""
 #   print("#"+str(counterafter)+ " counterafter")
 #   print("#"+str(counterafter1)+ " counterafter1")

#    if counterafter != 100:
#        emit(0,"loadv",counterafter )        
        
    emit(0, "loadv", counterafter1)
    emit(0, "store", 1)
    emit(0, "call", 400)
    emit(400, "load-Ind", 0)
    emit(401, "jumpeq", 405)
    emit(402, "writech",0)
    emit(403, "increment", 1)
    emit(404, "jump", 400)
    emit(405, "return", '')
    

#===============================================================================
def readStmt():
#===============================================================================
    """   <readStmt> ::= read <vars>"""
    
    getoken()
       
    emit(0, "readint", 7)
    emit(0, "store", 502)
    getoken()
#    writeStmt()
    
#===============================================================================
def writeStmt():
#===============================================================================
    """   <writeStmt> ::= read <vars>"""
    
    getoken()
#    emit(0,"load", 501)   
#    emit(0, "writeint", 501)

    
        
#===============================================================================
def assignStmt():
#===============================================================================
    """
        <id> = <expression>
    """
    whichidentifier = token  # Remember which ID on Left
    getoken()  # Get token after identifier
    if token.token == assignsym:
        getoken()
    elif token.token == leftsquarebrace:
        vars()
    elif token.token == leftbrace:
        vars()
    elif token.token == jumpeq:
        getoken()
    elif token.token == jumpne:
        getoken()
    elif token.token == rightbracket:
        getoken()
    elif token.token == lessthanequal:

        getoken()
    elif token.token == comma:
        getoken()
    elif token.token == greaterthanequal:
       getoken()
    # elif token.token == idsym: factor()
    else:
        error("Expected = in assignment statement")
    expression()
    # Save result into LHS runtime address
    
#===============================================================================   
def ifStmt():
# if-then-else
#===============================================================================
    """   <ifStmt> ::= if <expression>"""
    
    print("#IFSmt")
    getoken()  # skip "if"  
    expression()
    stmt()
    expression()

#===============================================================================
def elseStmt():
# if-then-else
#===============================================================================
    """   <elseStmt> ::= else <expression>"""
    
    print("#ElseSmt")
    emit(200, "jump", 47) # less than 2 go to else
    getoken()
    stmt()
    expression()
#    emit(314, "jump", 22)
#===============================================================================
def whileStmt():
#===============================================================================
    """   <whileStmt> ::= while (condition)statement"""
    
#    emit(0, "load", 201)
    emit(0, "store", 502)
    getoken()
    expression()  # num>0
#    emit(0, "jump", 22)
    stmt()
    
#===============================================================================
def expression():
#===============================================================================
    """
       Leaves result in ACC at runtime
       Use addresses 999 & 998 as Temporary variables

       <expression> ::=  <factor> {  (+ | -)  <factor> }
    """

    if token.token == leftbracket: getoken()

    factor()

## 1st start==============================================================================    
    while token.token == plus or token.token == minus or token.token == mpy or token.token == div or token.token == lessthan or token.token == greaterthan or token.token == lessthanequal or token.token == greaterthanequal or token.token == jumpne or token.token == jumpeq:
        op = token  # remember -
        getoken()  # skip past -
        # emit(0, "store", 997) # Save current result
        factor()
        
        if op.token == plus:
            emit(0, "add", 502)
            emit(0, "store", 502)
 #           emit(0, "jump", 22)
 #       if op.token == leftbracket:getoken()
        
        if op.token == minus:
## 2nd start==============================================================================    
            if token.token == plus or token.token == minus or token.token == mpy or token.token == div:
                op2 = token# remember *
                getoken()  # skip past *
                factor()
                
                if op2.token == plus:  # Subtract - have to swap operand order
                    emit(0, "load", 210)
                    emit(0, "add", 203)
                    emit(0, "store", 500)
                    
                
                if op2.token == minus:  # Subtract - have to swap operand order
                    emit(0, "load", 501)
                    emit(0, "subtract", 201)
                    emit(0, "store", 501)
            
                if op2.token == mpy:
## 3rd start==============================================================================    
                    while token.token == plus or token.token == minus or token.token == mpy or token.token == div:
                        op3 = token# remember *
                        getoken()  # skip past *
                        factor()
                        
                        if op3.token == plus:  # Subtract - have to swap operand order
                            emit(0, "load", 210)
                            emit(0, "add", 203)
                            emit(0, "store", 500)
                                        
                        if op3.token == minus:  # Subtract - have to swap operand order
                            emit(0, "load", 501)
                            emit(0, "subtract", 210)
                            emit(0, "store", 501)
                
                        if op3.token == mpy:
                            factor()
## 4th start==============================================================================    
                            while token.token == plus or token.token == minus or token.token == mpy or token.token == div:                    
                        
                                if token.token == plus:
                                    op4 = token# remember +
                                    getoken()  # skip past +
                                    factor()
                        
                                    if op4.token == plus:  # Subtract - have to swap operand order
                                        emit(0, "load", 210)
                                        emit(0, "add", 203)
                                        emit(0, "store", 500)
                    
                                if token.token == minus:
                                    op4 = token# remember -
                                    getoken()  # skip past -
                                    factor()
                        
                                    if op4.token == minus:  # Subtract - have to swap operand order
                                        emit(0, "load", 210)
                                        emit(0, "subtract", 203)
                                        emit(0, "store", 500)
                        
                                if token.token == mpy:
                                    op4 = token
                                    getoken()
                                    factor()
                        
                                    if op4.token == mpy:  # Subtract - have to swap operand order
                                        emit(0, "load", 210)
                                        emit(0, "mpy", 203)
                                        emit(0, "store", 500)
                                
                                if token.token == div:
                                    op4 = token
                                    getoken()
                                    factor()
                        
                                    if op4.token == div:  # Subtract - have to swap operand order
                                        emit(0, "load", 210)
                                        emit(0, "div", 203)
                                        emit(0, "store", 500)
## 4th end==============================================================================
  
                        emit(0, "mpy", 205)
                        emit(0, "store", 501)
                        
## 3rd end==============================================================================
                    
                    emit(0, "mpy", 210)
                    emit(0, "store", 501)

## 2nd end==============================================================================
            else: 
                emit(0, "load", 501)
                emit(0, "subtract", 201)
                emit(0, "store", 501)
                emit(0, "jump", 24)   
                
        elif op.token == mpy:
            emit(0, "load", 206)
            emit(0, "mpy", 7)
            emit(0, "store", 502)

        elif op.token == minus:  # Subtract - have to swap operand order
            emit(0, "load", 590)
            emit(0, "subtract", 201)
            emit(0, "store", 501)
            emit(0, "writeInt", 502)
            
        elif op.token == div:
            emit(0, "load", 502)
            emit(0, "div", 202)
            emit(0, "store", 7)
   
        elif op.token == lessthan:
            emit(0, "load", 501)
            emit(0, "compare", 212)
            emit(0, "jumplt", 300)
            emit(300, "writeInt", 502)
            
        elif op.token == greaterthan:
            emit(0, "load", 208)
            emit(0, "compare", 7)
            emit(0, "jumpgt", 47)
            
        elif op.token == lessthanequal:
            emit(0, "load", 501)
            emit(0, "compare", 212)
            emit(0, "jumplt", 300)
            emit(300, "writeInt", 502)
            
        elif op.token == greaterthanequal:
            emit(0, "load", 501)
            emit(0, "compare", 212)
            emit(0, "jumpgt", 300)
            emit(300, "writeInt", 502)

        elif op.token == jumpne:
            emit(0, "load", 205)
            emit(0, "compare", 502)
            emit(0, "jumpne", 310)
            emit(0, "writeInt", 0)
            emit(0, "halt", 0)
            emit(310, "writeInt", 502)

        elif op.token == jumpeq:
            emit(0, "load", 501)
            emit(0, "compare", 200)
            emit(0, "jumpeq", 300)
#            emit(0, "halt", 0)
            emit(300, "writeInt", 502)
            emit(301, "jump",30)

#===============================================================================
def factor():
#===============================================================================
    """
      # FACTOR() - leaves result in ACC at runtime
          <factor> ::= identifier | number
    """

    if token.token == plus:
        getoken()
        # - (unary)
    elif token.token == minus:
        getoken()

    if token.token == idsym:
        emit(0, "load", token.address)
        getoken()

    elif token.token == stringsym:  #################
        print("#String: " + str(token.name))
        printMsg()
        getoken()
    elif token.token == number:

        emit(0, "loadv", token.value)
        emit(0, "store", 200 + token.value)
        getoken()
    elif token.token == commentstr:           
#        print ("#Comment: " + str(token.name))
        getoken()

    # elif token.token == assignsym:
    #     getoken()
    elif token.token == leftbracket:

        getoken()
        # print "this is token",tokenNames[token.token]
    elif token.token == leftsquarebrace: getoken()

    elif  token.token == rightbracket:

        getoken()
    elif token.token == breaksym:
        emit(0,"halt", 0)

    elif  token.token == lessthanequal:

        getoken()
    elif  token.token == greaterthanequal:

        getoken()
    elif  token.token == jumpeq:
        
        getoken()
    elif  token.token == rightsquarebrace:

        getoken()
    elif  token.token == semicolon:
        getoken()
        
    elif token.token == comma:
        getoken()

    elif  token.token == leftbrace:
       getoken()


    elif token.token == rightbrace:
         print("")
    elif token.token == ifsym:
        ifStmt()
    elif token.token == printsym:
        getoken()
    else:
        error("Start Of Factor Expected")

#===============================================================================
def function():
#===============================================================================
    if token.token == functionsym:
        getoken()
        
    if token.token == idsym:
        getoken()
    
    if token.token == varsym :
        vars()
        
        
    if token.token == declaresym :
        vars()
    
    if token.token == varsym :
        vars()
    
    if token.token == leftbrace:
        vars()
    
    stmtList()
    
    stmtList()
    
    if token.token == rightbrace:
        print "#---Function Finished---"

#===============================================================================
def program():
#===============================================================================

    if token.token == leftbrace:
        getoken()

    if token.token == programsym:

        getoken()
    # else: error("Program start with 'program' keyword")

    if token.token == idsym:

        getoken()

    # else: error("Program name expected")

    if token.token == semicolon:

        getoken()

    # else: error("Semicolon expected")

    if token.token == declaresym :
        vars()
    if token.token == varsym :
        vars()
    
    if token.token == functionsym:
        function()
    
    if token.token == leftbrace:
        getoken()

    stmtList()
    
    stmtList()
    
    if token.token == rightbrace:
        print "#***Compilation Finished****"




#======================================================================
def main():
#======================================================================
    global line
    global srcfile
    global charIndex

    initSymTbl()


    with open("test.txt") as srcfile:
#        out1file = open('output.obj','w')
        line = srcfile.read()
        # out1file.write("hello")
       #   print line

    charIndex = 0

    debugScanner = False
    if debugScanner:  # Scanner Test Routine - Read a line and display the tokens
       getoken()
       while token.token is not None:  # Skeleton for testing Scanner
           printToken(token)
#           y = str(token)
#           out1file.write(y)
           getoken()
       sys.exit(1)
    else:
        getoken()  # Parse Program according to the grammar
        program()


#===============================================================================
# Main Compiler starts here
#===============================================================================

print "#Microcompiler.py v0.2"
emit(0, "load", 9)
main()
# emit(0, "constant",  "'A'")                   #need in break,comment,exitloop,writer-if-read-write-ch   program
# emit(0, "constant",  10)
# emit(0, "constant",  12)
# emit(0, "constant",  25)
# emit(0, "constant",  -10)
"""
srcfile = open('tiny_1.txt', 'r')
lexer = shlex.shlex(srcfile)
for token in lexer:
    print repr(token)
"""

# getoken()


#=======================================================================
# *** That's it folks - written by Giovanni Moretti - April 27, 2011 ***
#=======================================================================

